#include "Analog_to_Digital.h"
#include "stm32f10x.h"

void init_adc(void){
    
    // 必须保证 分频之后 adc 的 时钟 小于 14Mhz
    // 否则 adc 处于超频模式，不稳定
    RCC_ADCCLKConfig(RCC_PCLK2_Div6);
    
    // 开启 ADC 时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
    
    GPIO_Init(GPIOA,&(GPIO_InitTypeDef){
        
        .GPIO_Pin=GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3,
        .GPIO_Mode = GPIO_Mode_AIN, // 配置为模拟输入模式
        .GPIO_Speed = GPIO_Speed_50MHz
    });
    
    // 把要进行adc转换的接口注册到常规通道中
    ADC_RegularChannelConfig(
        ADC1,
        ADC_Channel_0,
        1,
        ADC_SampleTime_55Cycles5
    );
    ADC_RegularChannelConfig(
        ADC1,
        ADC_Channel_1,
        2,
        ADC_SampleTime_55Cycles5
    );
    ADC_RegularChannelConfig(
        ADC1,
        ADC_Channel_2,
        3,
        ADC_SampleTime_55Cycles5
    );
    ADC_RegularChannelConfig(
        ADC1,
        ADC_Channel_3,
        4,
        ADC_SampleTime_55Cycles5
    );
    
    
    ADC_InitTypeDef ADC_InitStruct;
    
    ADC_StructInit(&ADC_InitStruct);
    // 连续转换
    ADC_InitStruct.ADC_ContinuousConvMode=ENABLE;
    // 此芯片的 adc 转换是 12位的
    // 但是寄存器是16位的
    // 这里选择右对齐，那么高四位就被设置为0
    // 如果是左对齐，那么最低4位就被设置为0
    ADC_InitStruct.ADC_DataAlign = ADC_DataAlign_Right;
    
    //ADC_ExternalTrigConv_None; 软件触发 adc
    // 配置了扫描模式和 连续转换之后
    // ADC 只要被触发一次就会连续的进行转换
    // 一般情况下，没必要使用定时器来触发
    ADC_InitStruct.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;//ADC_ExternalTrigConv_T2_CC2;
    
    // 配置adc为独立模式，不和其他adc模块合作使用
    ADC_InitStruct.ADC_Mode=ADC_Mode_Independent;
    // 要扫描通道的数量
    // 只有在开启扫描模式时才有效
    // 否则都只读取第一个通道
    ADC_InitStruct.ADC_NbrOfChannel=4;
    ADC_InitStruct.ADC_ScanConvMode=ENABLE;
    
    ADC_Init(ADC1,&ADC_InitStruct);
    
    // 使能外部触发转换
    //ADC_ExternalTrigConvCmd(ADC1,ENABLE);
    
    
    
    //ADC_ITConfig(ADC1,ADC_IT_EOC,ENABLE);
    
    //NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
    
    //NVIC_InitTypeDef nvic;
    //nvic.NVIC_IRQChannel=ADC1_2_IRQn;
    //nvic.NVIC_IRQChannelCmd = ENABLE;
    //nvic.NVIC_IRQChannelPreemptionPriority=3;
    //nvic.NVIC_IRQChannelSubPriority = 3;
    //NVIC_Init(&nvic);
    
    ADC_DMACmd(ADC1,ENABLE);
    
    ADC_Cmd(ADC1,ENABLE);
    
    // 校准
    ADC_ResetCalibration( ADC1);
    while(SET == ADC_GetResetCalibrationStatus(ADC1));
    ADC_StartCalibration(ADC1);
    while(SET == ADC_GetCalibrationStatus(ADC1));
}

